/**
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
** \file DistanceVector.h
** \version $Id: DistanceVector.h 22 2009-10-28 02:03:29Z rigdern $
*/

#ifndef _DISTANCEVECTOR_H
#define _DISTANCEVECTOR_H

#include <iterator>
#include <list>

typedef std::list<unsigned int> DistanceVector;

/** An iterator designed all combinations of n variables such that each variable
 * has a maximal possible value and all variables sum to some value h. Done
 * iteratively to avoid storing the results. 
 **/
class CombinatorialIterator : public std::iterator<std::input_iterator_tag, 
                                                   DistanceVector>
{
public:
  CombinatorialIterator();
  CombinatorialIterator(unsigned int height, 
			const DistanceVector& maximalVector);
  ~CombinatorialIterator();
  
  bool operator==(const CombinatorialIterator& other);
  bool operator!=(const CombinatorialIterator& other);
  
  CombinatorialIterator& operator++();
  CombinatorialIterator& operator++(int);
  
  const DistanceVector& operator*() const;
  const DistanceVector* operator->() const;
 
  /** A statically defined end variable signifying that no more combinations
   * exist for this and any CombinatorialIterator. */
  static const CombinatorialIterator& end()
  {
    static CombinatorialIterator endItr;
    return endItr;
  }

private:
  /** Private function for performing actual iteration. */
  void incrementMultiAttributeVector();
  
  typedef enum {FINISHED, SINGLE_ATTRIBUTE, MULTI_ATTRIBUTE} Mode;

  /** The current state of the CombinatorIterator */
  DistanceVector _currentVector;
  /** The current state in the form of an iterator. */
  DistanceVector::iterator _currentElt;
  /** Internal state variables used for incremental iteration. */
  unsigned int _currentHeight, _lastAttr, _pos;  
  unsigned int *_maximalElements, *_cutoffs;
  Mode _mode;
};

#endif
